﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using SmartSpace.Core;

using SmartSpace.Service.Data;
using SmartSpace.Core.Metadata.Workflow;
using System.Web.Services.Protocols;
using System.Xml;
using System.IO;
using System.Security.Principal;
using System.ServiceModel.Activation;
using System.Web.Security;

namespace SmartSpace.Service
{
    /// <summary>
    /// Summary description for SsWebService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class SsWebService : System.Web.Services.WebService
    {
        #region metadata

        [WebMethod]
        public SingleResult<ListMetadata> GetListMetadata(Guid workflowId, Guid activityId)
        {
            IMetadataService service = Global.Get<IMetadataService>();
            ICoreService baseService = Global.Get<ICoreService>();
            IWorkflowService wfService = Global.Get<IWorkflowService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);
            List<Role> roles = baseService.FindAssignedRoles(user);

            WorkflowMetadata workflow = service.FindWorkflow(workflowId);
            ActivityMetadata activity = workflow.Get(activityId);

            AuthorizedView view = wfService.GetView(activity, user);

            ListMetadata metadata = new ListMetadata();
            metadata.ActivityId = activityId;
            metadata.Fields = new List<Data.FieldMetadata>();
            // 获取视图中定义的可以在列表中显示的字段
            foreach (SmartSpace.Core.Metadata.Workflow.AuthorizedField item in view.Fields)
            {
                // 标识字段必须带着
                if (item.Property.IsIdentity)
                {
                    Data.FieldMetadata field = new Data.FieldMetadata();
                    field.Id = item.Id;
                    field.Name = item.Property.Name;
                    field.Caption = item.Property.Caption;
                    field.IsHidden = item.IsCanVisit;
                    metadata.Fields.Add(field);
                }
                else if (item.IsCanVisit)
                {
                    Data.FieldMetadata field = new Data.FieldMetadata();
                    field.Id = item.Id;
                    field.Name = item.Property.Name;
                    field.Caption = item.Property.Caption;
                    field.IsHidden = false;
                    metadata.Fields.Add(field);
                }
            }
            return new SingleResult<ListMetadata>(true, "获取成功!", metadata);
        }

        [WebMethod]
        public SingleResult<DetailMetadata> GetDetailMetadata(Guid workflowId, Guid activityId)
        {
            IMetadataService service = Global.Get<IMetadataService>();
            ICoreService baseService = Global.Get<ICoreService>();
            IWorkflowService wfService = Global.Get<IWorkflowService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);
            List<Role> roles = baseService.FindAssignedRoles(user);

            WorkflowMetadata workflow = service.FindWorkflow(workflowId);
            ActivityMetadata activity = workflow.Get(activityId);
            
            AuthorizedView view = wfService.GetView(activity, user);
            // 
            DetailMetadata metadata = new DetailMetadata();
            metadata.ActivityId = activityId;
            metadata.CanModify = view.IsCanModify;
            metadata.CanRemove = view.IsCanRemove;
            metadata.Fields = new List<Data.FieldMetadata>();

            // 获取视图中定义的可以在列表中显示的字段
            foreach (SmartSpace.Core.Metadata.Workflow.AuthorizedField item in view.Fields)
            {
                Data.FieldMetadata field = new Data.FieldMetadata();
                field.Id = item.Id;
                field.Name = item.Property.Name;
                field.Type = item.Property.Type.Name;
                field.Caption = item.Property.Caption;
               
                field.IsHidden = !item.IsCanVisit;
                field.CanModify = item.IsCanModify;

                metadata.Fields.Add(field);
            }
            return new SingleResult<DetailMetadata>(true, "获取成功!", metadata);
        }

        #endregion

        #region data

        /// <summary>
        /// 获取空的数据对象
        /// <para>空对象中包涵了一些初始值</para>
        /// </summary>
        /// <param name="workflowId"></param>
        /// <param name="activityId"></param>
        /// <returns></returns>
        [WebMethod]
        public SingleResult<DetailData> GetEmptyData(Guid workflowId, Guid activityId)
        {
            IMetadataService service = Global.Get<IMetadataService>();
            ICoreService baseService = Global.Get<ICoreService>();
            IWorkflowService wfService = Global.Get<IWorkflowService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);

            WorkflowMetadata workflow = service.FindWorkflow(workflowId);
            ActivityMetadata activity = workflow.Get(activityId);

            AuthorizedView view = wfService.GetView(activity, user);
            SmartSpace.Core.Data.DetailData data = wfService.GetEmptyData(view, user);

            // 
            DetailData detail = new DetailData();
            detail.WorkflowId = workflowId;
            detail.ActivityId = activityId;
            detail.Fields = new List<FieldData>();
            foreach (SmartSpace.Core.Data.FieldData item in data.Fields)
            {
                Data.FieldData field = new Data.FieldData();
                field.Id = item.Property.Id;
                field.Name = item.Property.Name;
                field.Value = item.GetValue();
                field.Text = item.Text;
                field.Type = item.Property.Type.Name;
                detail.Fields.Add(field);
            }

            return new SingleResult<DetailData>(true, "获取成功!", detail);
        }

        [WebMethod]
        public PagedResult<DetailData> GetListData(
            Guid workflowId, 
            Guid activityId, 
            int jobType, 
            int start, 
            int limit)
        {
            IWorkflowService wfService = Global.Get<IWorkflowService>();
            IMetadataService metadataService = Global.Get<IMetadataService>();
            ICoreService baseService = Global.Get<ICoreService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);
            WorkflowMetadata workflow = metadataService.FindWorkflow(workflowId);
            ActivityMetadata activity = workflow.Get(activityId);

            if(limit>100)
            {
                limit = 100;
            }
            else if (limit < 0)
            {
                limit = 1;
            }
            JobType eJobType = (JobType)jobType;
            List<DetailData> resultData = new List<DetailData>();
            SmartSpace.Core.Data.ListData listData = wfService.GetListData(workflow, activity, eJobType, user, start, limit);

            foreach (SmartSpace.Core.Data.SimpleData item in listData.Items)
            {
                DetailData data = new DetailData();
                data.Id = item.GetIdentity().GetValue<Guid>();
                data.WorkflowId = workflowId;
                data.ActivityId = activityId;
                data.Fields = new List<FieldData>();
                foreach (SmartSpace.Core.Data.FieldData fieldItem in item.Fields)
                {
                    FieldData field = new FieldData();
                    field.Id = fieldItem.Property.Id;
                    field.Name = fieldItem.Property.Name;
                    field.Value = fieldItem.GetValue();
                    field.Text = fieldItem.GetValue();
                    field.Type = fieldItem.Property.Type.Name;
                    data.Fields.Add(field);
                }
                resultData.Add(data);
            }

            return new PagedResult<DetailData>(true, "获取成功!", resultData, start, limit, resultData.Count);
        }

        [WebMethod]
        public SingleResult<DetailData> GetData(Guid workflowId, Guid activityId, Guid dataId)
        {
            IMetadataService service = Global.Get<IMetadataService>();
            ICoreService baseService = Global.Get<ICoreService>();
            IWorkflowService wfService = Global.Get<IWorkflowService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);

            WorkflowMetadata workflow = service.FindWorkflow(workflowId);
            ActivityMetadata activity = workflow.Get(activityId);

            AuthorizedView view = wfService.GetView(activity, user);
            SmartSpace.Core.Data.DetailData data = wfService.GetDetailData(view, dataId);

            // 
            DetailData detail = new DetailData();
            detail.WorkflowId = workflowId;
            detail.ActivityId = activityId;
            detail.Id = data.Id;
            detail.Fields = new List<FieldData>();
            foreach (SmartSpace.Core.Data.FieldData item in data.Fields)
            {
                Data.FieldData field = new Data.FieldData();
                field.Id = item.Property.Id;
                field.Name = item.Property.Name;
                field.Value = item.GetValue();
                field.Text = item.Text;
                field.Type = item.Property.Type.Name;
                detail.Fields.Add(field);
            }

            #region 获取数据对应的流程驱动事件
            detail.Events = new List<Data.EventMetadata>();
            List<SmartSpace.Core.Metadata.Workflow.EventMetadata> events = wfService.GetEvents(activity, data, user);
            foreach (SmartSpace.Core.Metadata.Workflow.EventMetadata item in events)
            {
                Data.EventMetadata @event = new Data.EventMetadata();
                @event.Id = item.Id;
                @event.Caption = item.Caption;
                detail.Events.Add(@event);
            }
            #endregion

            return new SingleResult<DetailData>(true, "获取成功!", detail);
        }

        [WebMethod]
        public SingleResult<DetailData> CreateData(DetailData data)
        {
            IWorkflowService wfService = Global.Get<IWorkflowService>();
            IMetadataService metadataServcie = Global.Get<IMetadataService>();
            ICoreService baseService = Global.Get<ICoreService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);

            WorkflowMetadata workflow = metadataServcie.FindWorkflow(data.WorkflowId);
            ActivityMetadata activity = workflow.Get(data.ActivityId);

            AuthorizedView view = wfService.GetView(activity, user);
            SmartSpace.Core.Data.DetailData detail = wfService.GetEmptyData(view, user);

            foreach (SmartSpace.Core.Data.FieldData field in detail.Fields)
            {
                foreach (FieldData item in data.Fields)
                {
                    if (!field.Property.IsIdentity && field.Property.Id == item.Id)
                    {
                        field.SetValue(item.Value);
                        field.Text = item.Text;
                        break;
                    }
                }
            }

            detail = wfService.CreateData(view, detail, user);
            if (detail == null)
            {
                return new SingleResult<DetailData>(false, "保存失败!", null);
            }

            data.Id = detail.GetIdentity().GetValue<Guid>();
            foreach (FieldData item in data.Fields)
            {
                foreach (SmartSpace.Core.Data.FieldData field in detail.Fields)
                {
                    if (field.Property.Id == item.Id)
                    {
                        item.Value = field.GetValue();
                        item.Text = field.Text;
                        break;
                    }
                }
            }

            #region 获取数据对应的流程驱动事件
            data.Events = new List<Data.EventMetadata>();
            List<SmartSpace.Core.Metadata.Workflow.EventMetadata> events = wfService.GetEvents(activity, detail, user);
            foreach (SmartSpace.Core.Metadata.Workflow.EventMetadata item in events)
            {
                Data.EventMetadata @event = new Data.EventMetadata();
                @event.Id = item.Id;
                @event.Caption = item.Caption;
                data.Events.Add(@event);
            }
            #endregion

            return new SingleResult<DetailData>(true, "保存成功!", data);
        }

        [WebMethod]
        public BaseResult Save(DetailData data)
        {
            IWorkflowService wfService = Global.Get<IWorkflowService>();
            IMetadataService metadataServcie = Global.Get<IMetadataService>();
            ICoreService baseService = Global.Get<ICoreService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);
            
            WorkflowMetadata workflow = metadataServcie.FindWorkflow(data.WorkflowId);
            ActivityMetadata activity = workflow.Get(data.ActivityId);

            AuthorizedView view = wfService.GetView(activity, user);
            SmartSpace.Core.Data.DetailData detail = null;
            if(data.Id == default(Guid))
            {
                detail = wfService.GetEmptyData(view, user);
            }
            else
            {
                detail = wfService.GetDetailData(view, data.Id);
            }

            #region 将ws数据复制给core数据
            foreach (FieldData item in data.Fields)
            {
                foreach (SmartSpace.Core.Data.FieldData field in detail.Fields)
                {
                    // 标识字段不能被更新
                    if (!field.Property.IsIdentity && field.Property.Id == item.Id)
                    {
                        field.SetValue(item.Value);
                        break;
                    }
                }
            }
            #endregion

            wfService.Save(view, detail, user);
            return new BaseResult(true, "保存成功!"); 
        }

        /// <summary>
        /// 保存对象并将对象返回
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [WebMethod]
        public SingleResult<DetailData> SaveAndReturn(DetailData data)
        {
            IDataService servcie = Global.Get<IDataService>();
            IMetadataService metadataServcie = Global.Get<IMetadataService>();
            ICoreService baseService = Global.Get<ICoreService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);

            WorkflowMetadata workflow = metadataServcie.FindWorkflow(data.WorkflowId);
            ActivityMetadata activity = workflow.Get(data.ActivityId);

            AuthorizedView view = metadataServcie.FindView(activity, user);

            SmartSpace.Core.Data.DetailData detail = null;
            if (data.Id == default(Guid))
            {
                detail = servcie.GetEmpty(activity.View, user);
            }
            else
            {
                detail = servcie.GetDetailData(activity.View, data.Id);
            }
            foreach (SmartSpace.Core.Data.FieldData field in detail.Fields)
            {
                foreach (FieldData item in data.Fields)
                {
                    if (!field.Property.IsIdentity && field.Property.Id == item.Id)
                    {
                        field.SetValue(item.Value);
                        break;
                    }
                    //SmartSpace.Core.Data.FieldData field = new Core.Data.FieldData();
                    //field.m
                }
            }
            SmartSpace.Core.Data.DetailData returnData = servcie.Store(user, detail, view);
            if(returnData == null)
            {
                return new SingleResult<DetailData>(false, "保存失败!", null);
            }

            foreach (FieldData item in data.Fields)
            {
                foreach (SmartSpace.Core.Data.FieldData field in returnData.Fields)
                {
                    if (field.Property.Id == item.Id)
                    {
                        field.SetValue(item.Value);
                        item.Value = field.GetValue();
                        item.Text = field.Text;
                        break;
                    }

                }
            }

            return new SingleResult<DetailData>(true, "保存成功!", data);
        }

        #endregion

        #region workflow
        [WebMethod]
        public BaseResult Drive(Guid workflowId, Guid activityId,  Guid eventId, DetailData data, SmartSpace.Service.Data.User receiver)
        {
            IWorkflowService wfService = Global.Get<IWorkflowService>();

            ICoreService baseService = Global.Get<ICoreService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);
            WorkflowMetadata workflow = Global.Get<IMetadataService>().FindWorkflow(workflowId);
            ActivityMetadata activity = workflow.Get(data.ActivityId);
            SmartSpace.Core.Metadata.Workflow.EventMetadata @event = workflow.GetEvent(eventId);
            AuthorizedView view = wfService.GetView(activity, user);
            SmartSpace.Core.Data.DetailData detail = wfService.GetDetailData(view, data.Id);

            foreach (SmartSpace.Core.Data.FieldData field in detail.Fields)
            {
                foreach (FieldData item in data.Fields)
                {
                    if (!field.Property.IsIdentity && field.Property.Id == item.Id)
                    {
                        field.SetValue(item.Value);
                        break;
                    }
                    //SmartSpace.Core.Data.FieldData field = new Core.Data.FieldData();
                    //field.m
                }
            }

            wfService.Save(user, detail, workflow);
            SmartSpace.Core.Workflow.WorkflowInstance instance = wfService.GetInstance(detail);
            if (instance == null)
            {
                // 启动流程实例
                instance = wfService.Start(workflow, activity, detail, user);
            }

            if (instance != null)
            {
                // 驱动流程
                SmartSpace.Core.User receiveUser = baseService.FindUser(receiver.Account);
                wfService.Drive(instance, @event, detail, user, receiveUser);
                return new BaseResult(true, "");
            }
            else
            {
                return new BaseResult(false, "");
            }
        }

        [WebMethod]
        public ListResult<Data.User> GetUsers(Guid workflowId, Guid eventId)
        {
            IWorkflowService wfService = Global.Get<IWorkflowService>();

            ICoreService baseService = Global.Get<ICoreService>();

            SmartSpace.Core.User user = baseService.FindUser(User.Identity.Name);
            WorkflowMetadata workflow = Global.Get<IMetadataService>().FindWorkflow(workflowId);
            SmartSpace.Core.Metadata.Workflow.EventMetadata @event = workflow.GetEvent(eventId);

            List<Data.User> users = new List<Data.User>();
            foreach (ActivityRight item in @event.ToActivity.Rights)
            {
                SmartSpace.Core.Role role = baseService.FindRole(item.RoleId);
                List<SmartSpace.Core.User> coreUsers = baseService.FindContainsUsers(role);
                foreach (SmartSpace.Core.User userItem in coreUsers)
                {
                    Data.User dataUser = new Data.User();
                    dataUser.Account = userItem.Account;
                    dataUser.Caption = userItem.Name;
                    dataUser.Id = userItem.Id;
                    dataUser.RoleId = role.Id;
                    dataUser.RoleCaption = role.Caption;
                    users.Add(dataUser);
                }
            }
            return new ListResult<Data.User>(true, "获取成功!", users);
        }
        #endregion

        /// <summary>
        /// 获取可以访问的导航列表
        /// </summary>
        /// <returns></returns>
        [WebMethod]
        public ListResult<NavigationModel> GetNavigations()
        {
            List<NavigationModel> models = new List<NavigationModel>();

            ICoreService service = Global.Get<ICoreService>();
            List<SmartSpace.Core.Base.Navigation> navigations = service.FindNavigations();
            for(int index = 0; index < navigations.Count; index++)
            {
                models.Add(ConvertNavigation(navigations[index]));
            }
            return new ListResult<NavigationModel>(true, "获取成功", models);
        }

        private NavigationModel ConvertNavigation(SmartSpace.Core.Base.Navigation navigation)
        {
            NavigationModel model = new NavigationModel();
            model.Id = navigation.Id;
            model.ViewId = navigation.View.Id;
            model.ViewName = navigation.View.Name;
            model.ViewCaption = navigation.View.Caption;
            model.Caption = navigation.Caption;
            model.Arguments = navigation.Arguments;
            if (navigation.Children != null && navigation.Children.Count > 0)
            {
                model.Children = new List<NavigationModel>();
                foreach (SmartSpace.Core.Base.Navigation item in navigation.Children)
                {
                    model.Children.Add(ConvertNavigation(item));
                }
            }
            return model;
        }

        [WebMethod]
        public BaseResult Login(string username, string password)
        {
            System.Web.Security.FormsAuthentication.SetAuthCookie(username, true);
            // 创建验证票
            //System.Web.Configuration.FormsAuthenticationConfiguration formsConfig = new System.Web.Configuration.FormsAuthenticationConfiguration();
            //FormsAuthenticationTicket formAuthTicket = new FormsAuthenticationTicket(
            //            1,                              // 版本
            //            username,                          // 用户名称
            //            DateTime.Now,                   // 创建时间
            //            DateTime.Now.AddMinutes(formsConfig.Timeout.TotalMinutes),    // 失效时间
            //            true,
            //            "");    // 用户数据

            //加密票
            //string encryptedTicket = FormsAuthentication.Encrypt(formAuthTicket);
            // 以加密票的密文存入Cookie
            //HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);

            //authCookie.HttpOnly = true;
            //authCookie.Path = FormsAuthentication.FormsCookiePath;
            //authCookie.Secure = FormsAuthentication.RequireSSL;
            //if (FormsAuthentication.CookieDomain != null)
            //{
            //    authCookie.Domain = FormsAuthentication.CookieDomain;
            //}
            //if (formAuthTicket.IsPersistent)
            //{
            //    authCookie.Expires = formAuthTicket.Expiration;
            //}
            //HttpContext.Current.Response.Cookies.Add(authCookie);
            //FormsIdentity identity = new FormsIdentity(formAuthTicket);
            //GenericPrincipal principal = new GenericPrincipal(identity, null);
            //HttpContext.Current.User = principal;

            //PassportTicket ticket = new PassportTicket(formAuthTicket, encryptedTicket, app);
            //if (ticket.Save())
            //{
            //    return ticket.Ticket.PublicTicket;
            //}
            return new BaseResult(true, "登录成功!");
        }
    }
}
